﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Bee.Models;
using Bee.Web;
using Bee.Data;
using Bee.Logging;
using System.Data;
using Bee.Util;

namespace Bee.Controllers
{

    public class DBTransferStatus
    {
        public string Name
        {
            get;
            set;
        }

        public string Status
        {
            get;
            set;
        }
    }

    public class DBManager
    {
        private static DBManager instance = new DBManager();

        private Dictionary<string, Dictionary<string, string>> dict = new Dictionary<string, Dictionary<string, string>>();

        private DBManager()
        {
        }

        public static DBManager Instance
        {
            get
            {
                return instance;
            }
        }

        public Dictionary<string, string> GetStatus(string name)
        {
            Dictionary<string, string> result = null;

            if (dict.ContainsKey(name))
            {
                result = dict[name];
            }

            return result;
        }

        public void Register(string name, Dictionary<string, string> list)
        {
            dict[name] = list;
        }
    }

    public class DBManagerController : ControllerBase
    {

        static DBManagerController()
        {
            DataMapping.Instance.Register("DBProvider", () =>
            {
                Dictionary<string, string> dict = new Dictionary<string, string>();
                dict.Add("System.Data.SQLite", "sqlite");
                dict.Add("System.Data.SqlClient", "SqlServer");
                dict.Add("MySql.Data.MySqlClient", "mysql");

                return dict;

            });
        }

        public PageResult Index()
        {
            ViewData.Add("srcConnection", @"data source=.\App_Data\AuthDB.db;");
            ViewData.Add("targetConnection", @"data source=192.168.18.160\devdemo;initial catalog=HKFTest1;user id=sa;password=devdemo@dba");

            return View();
        }

        public ActionResult ShowResult()
        {
            return View(DBManager.Instance.GetStatus("dbsrcTransfer" + Session.SessionID));
        }

        public object DBList()
        {
            using (DbSession dbSession = new DbSession("mysqldb"))
            {
                //return dbSession.GetDbObject();

                return dbSession.GetSpSchema("getnow");
            }
        }

        public void Transfer()
        {

            string srcProvider = ViewData.TryGetValue<string>("srcProvider", string.Empty);
            string srcConnection = ViewData.TryGetValue<string>("srcConnection", string.Empty);
            string targetProvider = ViewData.TryGetValue<string>("targetProvider", string.Empty);
            string targetConnection = ViewData.TryGetValue<string>("targetConnection", string.Empty);

            DbSession.Register("dbsrcTransfer" + Session.SessionID, srcProvider, srcConnection);
            DbSession.Register("dbtargetTransfer" + Session.SessionID, targetProvider, targetConnection);

            List<DbObject> list = null;
            Dictionary<string, string> statusResult = new Dictionary<string, string>();
            using (DbSession srcDbSession = new DbSession("dbsrcTransfer" + Session.SessionID))
            {
                list = (from item in srcDbSession.GetDbObject() where item.ObjectType == DbObjectType.Table
                            select item).ToList();
                
                foreach(DbObject dbObject in list)
                {

                    statusResult.Add(dbObject.DbObjectName, "Init");
                }

                DBManager.Instance.Register(srcDbSession.ConnectionName, statusResult);

                foreach (DbObject dbObject in list)
                {
                    try
                    {
                        TableSchema tableSchema = srcDbSession.GetTableSchema(dbObject.DbObjectName);

                        using (DbSession targetDbSession = new DbSession("dbtargetTransfer" + Session.SessionID))
                        {
                            string createTableScript = targetDbSession.ToCreateTableScript(tableSchema);


                            targetDbSession.ExecuteCommand(createTableScript, null);
                        }

                        statusResult[dbObject.DbObjectName] = "创建表成功！";
                    }
                    catch (Exception e)
                    {
                        statusResult[dbObject.DbObjectName] = e.Message;
                        Logger.Error(string.Format("Trasfer object {0} error!", dbObject.DbObjectName), e);
                    }
                    //System.Threading.Thread.Sleep(1000);
                }

                foreach (DbObject dbObject in list)
                {
                    try
                    {
                        DataTable dataTable = srcDbSession.Query(dbObject.DbObjectName, null);

                        using (DbSession targetDbSession = new DbSession("dbtargetTransfer" + Session.SessionID, true))
                        {
                            if (targetProvider.Contains("System.Data.SqlClient"))
                            {
                                targetDbSession.ExecuteCommand("set identity_insert {0} on".FormatWith(dbObject.DbObjectName), null);
                            }

                            foreach (DataRow row in dataTable.Rows)
                            {
                                
                                targetDbSession.Insert(dbObject.DbObjectName, BeeDataAdapter.From(row), false);
                            }

                            if (targetProvider.Contains("System.Data.SqlClient"))
                            {
                                targetDbSession.ExecuteCommand("set identity_insert {0} off".FormatWith(dbObject.DbObjectName), null);
                            }

                            targetDbSession.CommitTransaction();
                        }

                        statusResult[dbObject.DbObjectName] += "传输数据成功！";
                        //System.Threading.Thread.Sleep(1000);
                    }
                    catch (Exception e)
                    {
                        statusResult[dbObject.DbObjectName] = "传输数据出错！" + e.Message;
                        Logger.Error(string.Format("Trasfer object {0} error!", dbObject.DbObjectName), e);
                    }
                }
            }
        }
    }
}
